package cn.ywang.spring.framework.aop.aspect;

import cn.ywang.spring.framework.aop.intercept.Joinpoint;

import java.lang.reflect.Method;

/**
 * @author BeatificWang
 * @date 2019/5/4 21:35
 */
public abstract class AbstractAspectAdvice implements Advice {
	private Method aspect;
	private Object target;

	public AbstractAspectAdvice(Method aspect, Object target) {
		this.aspect = aspect;
		this.target = target;
	}

	public Object invokeAdviceMethod(Joinpoint joinPoint, Object returnValue, Throwable tx) throws Throwable {
		Class<?>[] paramTypes = this.aspect.getParameterTypes();
		if (null == paramTypes || paramTypes.length == 0) {
			return this.aspect.invoke(this.target);
		}
		else {
			Object[] args = new Object[paramTypes.length];
			for (int i = 0; i < paramTypes.length; i++) {
				if (paramTypes[i] == Joinpoint.class) {
					args[i] = joinPoint;
				}
				else if (paramTypes[i] == Throwable.class) {
					args[i] = tx;
				}
				else if (paramTypes[i] == Object.class) {
					args[i] = returnValue;
				}
			}
			return this.aspect.invoke(this.target, args);
		}
	}
}
